package com.sunck.common.shiro;

import com.sunck.common.utils.RedisUtils;
import com.sunck.common.utils.Servlets;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * 自定义授权会话管理类
 *
 * @author LengChen
 * @version 1.0
 * @date 2020/8/7
 */
public class RedisSessionDao extends AbstractSessionDAO {

    private static final Logger logger = LoggerFactory.getLogger(RedisUtils.class);


    // Session超时时间，单位为毫秒
    private int expireTime = 120000;

    @Autowired
    private RedisUtils redisUtils;

    private String sessionKeyPrefix = "shiro_session_";

    public RedisSessionDao() {
        super();
    }

    public RedisSessionDao(int expireTime,String keyName) {
        super();
        this.expireTime = expireTime;
        this.sessionKeyPrefix = keyName;
    }


    @Override // 创建session
    protected Serializable doCreate(Session session) {
        Serializable sessionId = this.generateSessionId(session);
        this.assignSessionId(session, sessionId);
        this.update(session);
        return sessionId;
    }

    @Override // 读取session
    protected Session doReadSession(Serializable sessionId) {
        if (sessionId == null) {
            return null;
        }
        Session session = null;
        HttpServletRequest request = Servlets.getRequest();
        if (request != null){
//            String uri = request.getServletPath();
            session = (Session)request.getAttribute("session_"+sessionId);
        }
        if (session == null){
            session = redisUtils.getObject(sessionKeyPrefix + sessionId);
            if(request != null){
                request.setAttribute("session_"+sessionId, session);
            }
        }
        return session;
    }


    @Override   //更新session
    public void update(Session session) throws UnknownSessionException {
        if (session == null || session.getId() == null) {
            return;
        }
        //静态文件不更新session
        HttpServletRequest request = Servlets.getRequest();
        if(Servlets.isStaticFile(request.getServletPath())){
            return;
        }
        session.setTimeout(expireTime);
        //redisTemplate.opsForValue().set(session.getId(), session, expireTime, TimeUnit.MILLISECONDS);
        redisUtils.setObject(sessionKeyPrefix + session.getId(),session,expireTime);
        redisUtils.setHash(sessionKeyPrefix,sessionKeyPrefix + session.getId(),session.getTimeout() + "|" + session.getLastAccessTime().getTime());
        logger.debug("updateSession {} {}", sessionKeyPrefix+ session.getId(),expireTime);
    }

    @Override
    public void delete(Session session) {
        if (null == session) {
            return;
        }
        HttpServletRequest request = Servlets.getRequest();
        if (request != null) {
//            String uri = request.getServletPath();
            request.removeAttribute("session_" + session.getId());
        }
        redisUtils.removeKey(sessionKeyPrefix + session.getId());
    }

    @Override
    public Collection<Session> getActiveSessions() {
        List<Session> list = new ArrayList<Session>();
        Set<String> keySet = redisUtils.getKeys(sessionKeyPrefix + "*");
        for(String str : keySet){
            list.add(redisUtils.getObject(str));
        }
        return list;
    }

    public String getSessionKeyPrefix() {
        return sessionKeyPrefix;
    }

    public void setSessionKeyPrefix(String sessionKeyPrefix) {
        this.sessionKeyPrefix = sessionKeyPrefix;
    }
    public int getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(int expireTime) {
        this.expireTime = expireTime;
    }
}
